-
Notifications
You must be signed in to change notification settings - Fork 25.6k
[ML] Refactor inference API service tests base classes #135461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ML] Refactor inference API service tests base classes #135461
Conversation
| var chunkingSettings = extractChunkingSettings(config, taskType); | ||
| ChunkingSettings chunkingSettings = null; | ||
| if (TaskType.TEXT_EMBEDDING.equals(taskType)) { | ||
| chunkingSettings = ChunkingSettingsBuilder.fromMap(removeFromMapOrDefaultEmpty(config, ModelConfigurations.CHUNKING_SETTINGS)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the bug fix. extractChunkingSettings was using removeFromMap which if the settings don't exist it would provide null to the ChunkingSettingsBuilder.fromMap(). We intentionally do this when parsing from persistent state to handle backwards compatibility I think.
I don't think the change here in parseRequestConfig will cause any backwards compatibility issues. For new endpoints being created we'll use the newer default chunking settings instead though.
| // To find this information you need to access your account's limits https://platform.openai.com/account/limits | ||
| // 500 requests per minute | ||
| private static final RateLimitSettings DEFAULT_RATE_LIMIT_SETTINGS = new RateLimitSettings(500); | ||
| public static final RateLimitSettings DEFAULT_RATE_LIMIT_SETTINGS = new RateLimitSettings(500); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making various things public so they can be accessible in tests that are outside of the package.
| ); | ||
| } | ||
|
|
||
| public static String parsePersistedConfigErrorMsg(String inferenceEntityId, String serviceName, TaskType taskType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a new version of the error message to make the error more clear. Ideally all of the services will switch to use this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to switch the services to use the new method in this PR? There are a dozen tests that would need to be updated to reflect the new message, but it would be nice to have consistency across all services.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep I can do that 👍
| } | ||
|
|
||
| @Override | ||
| protected void assertRerankerWindowSize(RerankingInferenceService rerankingInferenceService) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding this to the configuration of the tests so that it can be leveraged by CustomServiceTests and CustomServiceParameterizedTests.
| } | ||
|
|
||
| @Override | ||
| public InferenceService createInferenceService() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was pushed into the abstract base class
| @@ -0,0 +1,387 @@ | |||
| /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason this class exists and isn't included in AbstractInferenceServiceTests is adding parameterized tests in AbstractInferenceServiceTests results in the the non parameterized tests being run for each permutation, even though those tests don't depend on the parameterized test information.
It seemed cleaner to separate them 🤷♂️
| { | ||
| new TestCaseBuilder( | ||
| "Test parsing persisted config without chunking settings", | ||
| testConfiguration -> getPersistedConfigMap( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test configurations have to be passed in because the parameters() method must be static
| */ | ||
| public abstract class AbstractInferenceServiceTests extends InferenceServiceTestCase { | ||
|
|
||
| protected final MockWebServer webServer = new MockWebServer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pulled this logic into the base class
| protected abstract Map<String, Object> createTaskSettingsMap(); | ||
|
|
||
| protected abstract Map<String, Object> createSecretSettingsMap(); | ||
| public void testParseRequestConfig_CreatesAnEmbeddingsModel() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The *ParseRequestConfig_* tests could be converted into parameterized tests as well. I decided to not do it in this PR because it's already quite a few changes.
| protected abstract Map<String, Object> createTaskSettingsMap(); | ||
|
|
||
| protected abstract Map<String, Object> createSecretSettingsMap(); | ||
| public void testParseRequestConfig_CreatesAnEmbeddingsModel() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm adding a few tests that were in OpenAiServiceTests to make them common.
…tor-tests-abstract
…ner/elasticsearch into ml-refactor-tests-abstract
|
Pinging @elastic/ml-core (Team:ML) |
| ); | ||
| } | ||
|
|
||
| public static String parsePersistedConfigErrorMsg(String inferenceEntityId, String serviceName, TaskType taskType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to switch the services to use the new method in this PR? There are a dozen tests that would need to be updated to reflect the new message, but it would be nice to have consistency across all services.
|
|
||
| public static String parsePersistedConfigErrorMsg(String inferenceEntityId, String serviceName, TaskType taskType) { | ||
| return format( | ||
| "Failed to parse stored model [%s] for [%s] service, error: [%s]. Please delete and add the service again", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would deleting and adding the service again actually help if the task type was unsupported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think deleting is probably the only solution here. I think this would only occur if the the inference endpoint got corrupted somehow. Basically this is saying that the persisted inference endpoint is stating it is leverage a particular task type that is not supported. The request context parsing should prevent getting into that scenario. But if we had a regression or the endpoint was corrupted somehow we could.
| serviceSettingsMap, | ||
| secretSettingsMap, | ||
| parsePersistedConfigErrorMsg(modelId, NAME) | ||
| parsePersistedConfigErrorMsg(modelId, NAME, taskType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To reduce some code duplication and prevent us from constructing a String that we might never use every time we call parseRequestConfig(), I think it should be possible to move the parsePersistedConfigErrorMsg() call down into createModel() along with the unsupportedTaskTypeErrorMsg() call used for the REQUEST context and only call them (which one we call would depend on the context passed in to createModel()) when throwing an exception that would need the message.
I haven't checked every Service to see if this would work for all of them, but I assume that the structure is pretty similar between implementations.
| private static ChunkingSettings extractChunkingSettings(Map<String, Object> config, TaskType taskType) { | ||
| if (TaskType.TEXT_EMBEDDING.equals(taskType)) { | ||
| return ChunkingSettingsBuilder.fromMap(removeFromMap(config, ModelConfigurations.CHUNKING_SETTINGS)); | ||
| } | ||
|
|
||
| return null; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to keep using this method in the two places below, where the behaviour is unchanged, rather than duplicating the logic?
…tor-tests-abstract
…tor-tests-abstract
|
|
||
| private static ChunkingSettings extractPersistentChunkingSettings(Map<String, Object> config, TaskType taskType) { | ||
| if (TaskType.TEXT_EMBEDDING.equals(taskType)) { | ||
| // note there's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfinished comment
…ner/elasticsearch into ml-refactor-tests-abstract
…tor-tests-abstract
This PR refactors a base test class for testing service classes (e.g.
OpenAiService).Highlights
parsePersistedConfigfrom OpenAI were moved toAbstractInferenceServiceParameterizedTestsso they can be leveraged for all classes that extend from itAbstractInferenceServiceParameterizedTestswhich uses parameterized tests to represent theparsePersistedConfigandparsePersistedConfigWithSecretstests they can be removed from each subclassed testsparsePersistedConfigWithSecretstests from theAbstractInferenceServiceTeststoAbstractInferenceServiceParameterizedTests